﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Model;
using BankingSystem.Dal.Repository;

namespace BankingSystem.BLL
{
    /// <summary>
    /// Класс "Банк"
    /// </summary>
    public class Bank : BankingSystem.BLL.IBank
    {
        #region Private

        /// <summary>
        /// список счетов банка
        /// </summary>
        private RepositoryBase<Account> Accounts;

        /// <summary>
        /// список клиентов банка
        /// </summary>
        private RepositoryBase<Client> Clients;

        #endregion
       
        #region Public Methods



        #region ClientService

        /// <summary>
        /// Метод: добавить нового клиента
        /// </summary>
        /// <returns>Клиент</returns>
        public Client CreateClient(ClientInfo clientInfo)
        {
            Client newClient = new Client(clientInfo);
            Clients.Insert(newClient);
            Clients.Save();
            return newClient;
        }

        public void UpdateClient(Client client)
        {
            Clients.Update(client);
            Clients.Save();
        }

        public void DeleteClient(Client client)
        {
            Clients.Delete(client);
            Clients.Save();
        }

        public IList<Client> FindByCriteria(Func<Client, bool> predicate )
        {
            return Clients.GetByCriteria(predicate).ToList();
        }

        #endregion

        #region AccountService
        /// <summary>
        /// Метод: создать новый счёт в банке
        /// </summary>
        /// <param name="client"></param>
        /// <returns>Счёт</returns>
        public Account CreateAccount(Client client, DateTime expireDate, double initBalance)
        {           
            Account newAccount = new Account(client.Id, expireDate, initBalance);
            Accounts.Insert(newAccount);
            Accounts.Save();
            Clients.Update(client);
            Clients.Save();
            return newAccount;
        }

        public void DeleteAccount(Account account)
        {
            Accounts.Delete(account);
            Accounts.Save();
        }
        /// <summary>
        /// Метод: перевод денег с одного счёта на другой
        /// </summary>
        public void Transfer(double amount, Account fromAccount, Account toAccount)
        {
            throw new NotImplementedException();
            // если счёт не найден - перевод денег невозможен
            if (fromAccount == null)
            {
                throw new Exception("Счёт-источник не найден");
            }

            // если счёт не найден - перевод денег невозможен
            if (toAccount == null)
            {
                throw new Exception("Счёт-приёмник не найден");
            }

            // Если операция по снятию денег со счёта прошла успешно
            fromAccount.MoneyDec(amount);
            // добавим снятые деньги на счёт-приёмник
            toAccount.MoneyInc(amount);

        }

        /// <summary>
        /// Метод: добавить деньги на счёт
        /// </summary>
        /// <param name="Acc">Счёт</param>
        /// <param name="Summ">Сумма</param>
        public void Deposite(Account Acc, double Summ)
        {
            throw new NotImplementedException();
            Acc.MoneyInc(Summ);
        }

        /// <summary>
        /// Метод: удалить деньги со счёта
        /// </summary>
        /// <param name="Acc">Счёт</param>
        /// <param name="Summ">Сумма</param>
        public void WithDraw(Account Acc, double Summ)
        {
            throw new NotImplementedException();
            Acc.MoneyDec(Summ);
        }
        #endregion


        // конструктор банка по умолчанию
        public Bank()
        {
            Accounts = new BinaryRepository<Account>("Accounts.bin");
            Accounts.CheckOut();
            Clients = new BinaryRepository<Client>("Clients.bin");
            Clients.CheckOut();
        }

        

        #endregion

        public IList<Account> FindClientAccounts(Client client)
        {
            
            return Accounts.GetByCriteria(x=>x.OwnerClientId == client.Id).ToList();
        }
        
    }
}
